//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V1.1.0
#include "timer_bsp.h"
#include "stm32f4xx_rcc.h"
#include "misc.h"


/*定时器总管理结构体*/
typedef struct
{
	void (*Basic_IT_CB)(void);        //基本中断回调函数
	WHT_DMA_Config_t DMA_Config_UP;   //DMA配置
    WHT_DMA_Config_t DMA_Config_CCR1; //DMA配置
	WHT_DMA_Config_t DMA_Config_CCR2;
	WHT_DMA_Config_t DMA_Config_CCR3;
	WHT_DMA_Config_t DMA_Config_CCR4;
}WHT_Data_t;

static WHT_Data_t WHT_TIMER1;
static WHT_Data_t WHT_TIMER2;
static WHT_Data_t WHT_TIMER3;
static WHT_Data_t WHT_TIMER4;
static WHT_Data_t WHT_TIMER5;
static WHT_Data_t WHT_TIMER6;
static WHT_Data_t WHT_TIMER7;
static WHT_Data_t WHT_TIMER8;
static WHT_Data_t WHT_TIMER9;
static WHT_Data_t WHT_TIMER10;
static WHT_Data_t WHT_TIMER11;
static WHT_Data_t WHT_TIMER12;
static WHT_Data_t WHT_TIMER13;
static WHT_Data_t WHT_TIMER14;

#define WHT_TIMER     ((WHT_Data_t*)config->Private_Data)//简化操作

/*基本定时器中断优先级配置*/
static void WHT_Timer_BSP_Basic_NVIC_Configuration(const WHT_Timer_Config_t *config)
{
	IRQn_Type IRQn;

    /* 配置中断源 */
    switch (config->Name)
    {
#if defined(STM32F410xx)
    case Timer1: IRQn = TIM1_UP_IRQn; break;
#else
	case Timer1: IRQn = TIM1_UP_TIM10_IRQn; break;
    case Timer2: IRQn = TIM2_IRQn; break;
    case Timer3: IRQn = TIM3_IRQn; break;
    case Timer4: IRQn = TIM4_IRQn; break;
#endif /* STM32F410xx */
    case Timer5: IRQn = TIM5_IRQn; break;
#if defined(STM32F412xG)
    case Timer6: IRQn = TIM6_IRQn; break;
#elif defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F410xx)\
      || defined(STM32F469_479xx) || defined(STM32F446xx) || defined(STM32F413_423xx)
    case Timer6: IRQn = TIM6_DAC_IRQn; break;
#endif
#if !defined(STM32F410xx) && !defined(STM32F401xx) && !defined(STM32F411xE)
    case Timer7: IRQn = TIM7_IRQn; break;
	case Timer8: IRQn = TIM8_UP_TIM13_IRQn; break;
#endif
    case Timer9: IRQn = TIM1_BRK_TIM9_IRQn; break;
#if !defined(STM32F410xx)
    case Timer10:IRQn = TIM1_UP_TIM10_IRQn; break;
#endif
    case Timer11:IRQn = TIM1_TRG_COM_TIM11_IRQn; break;
#if !defined(STM32F410xx) && !defined(STM32F401xx) && !defined(STM32F411xE)
    case Timer12:IRQn = TIM8_BRK_TIM12_IRQn; break;
	case Timer13:IRQn = TIM8_UP_TIM13_IRQn; break;
    case Timer14:IRQn = TIM8_TRG_COM_TIM14_IRQn; break;
#endif
    default:
        return;
    }

	NVIC_SetPriority(IRQn, ((WHT_Timer_Basic_Config_t*)config->Config)->PreemptionPriority);
	NVIC_EnableIRQ(IRQn);
}
/*高级定时器GPIO初始化*/
static void WHT_Timer_BSP_GPIO_Init(const WHT_Timer_Config_t* config)
{
	WHT_Timer_PWM_Out_Config_t* PWM_Config;

	PWM_Config = (WHT_Timer_PWM_Out_Config_t*)config->Config;

	for (unsigned char i = 0; i < config->Config_Count; i++)
	{
		/*输出比较通道GPIO*/
		WHT_GPIO_BSP.WHT_Set_Clock(PWM_Config[i].Normal_Output_GPIO_Port, ENABLE);
		WHT_GPIO_BSP.WHT_Set_Pin(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, Low);
		WHT_GPIO_BSP.WHT_Set_Mode(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, Mode_AF_PP);
		/*输出比较通道互补通道GPIO*/
		if (PWM_Config[i].Complementary_Output_State == ENABLE)
		{
			WHT_GPIO_BSP.WHT_Set_Clock(PWM_Config[i].CO_Output_GPIO_Port, ENABLE);
			WHT_GPIO_BSP.WHT_Set_Pin(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, Low);
			WHT_GPIO_BSP.WHT_Set_Mode(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, Mode_AF_PP);
		}
		/*输出比较通道刹车通道GPIO*/
		if (PWM_Config[i].Brake_Output_State == ENABLE)
		{
			WHT_GPIO_BSP.WHT_Set_Clock(PWM_Config[i].Brake_Output_GPIO_Port, ENABLE);
			WHT_GPIO_BSP.WHT_Set_Pin(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, Low);// BKIN引脚默认先输出低电平
			WHT_GPIO_BSP.WHT_Set_Mode(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, Mode_AF_PP);
		}

		switch (config->Name)
		{
		case Timer1:
		case Timer2://定时器1、2的复用功能是一家
			WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, AFIO_TIM1);
			if (PWM_Config[i].Complementary_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, AFIO_TIM1);
			if (PWM_Config[i].Brake_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, AFIO_TIM1);
			break;
		case Timer3:
		case Timer4:
		case Timer5://定时器3、4、5的复用功能是一家
			WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, AFIO_TIM3);
			if (PWM_Config[i].Complementary_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, AFIO_TIM3);
			if (PWM_Config[i].Brake_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, AFIO_TIM3);
			break;
		case Timer8:
		case Timer9:
		case Timer10:
		case Timer11://定时器8、9、10、11的复用功能是一家
			WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, AFIO_TIM8);
			if (PWM_Config[i].Complementary_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, AFIO_TIM8);
			if (PWM_Config[i].Brake_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, AFIO_TIM8);
			break;
		case Timer12:
		case Timer13:
		case Timer14:
			WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, AFIO_TIM12);
			if (PWM_Config[i].Complementary_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, AFIO_TIM12);
			if (PWM_Config[i].Brake_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, AFIO_TIM12);
			break;
		default:
			return;
		}
	}
}
/*定时器时钟源使能*/
static void WHT_Timer_BSP_Clock_Cmd(const WHT_Timer_Config_t* config, FunctionalState state)
{
    switch (config->Name)//开启定时器时钟
    {
    case Timer1: RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, state); break;
    case Timer2: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, state); break;
    case Timer3: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, state); break;
    case Timer4: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, state); break;
    case Timer5: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, state); break;
    case Timer6: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, state); break;
    case Timer7: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, state); break;
    case Timer8: RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, state); break;
    case Timer9: RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, state); break;
    case Timer10:RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, state);break;
    case Timer11:RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11, state);break;
    case Timer12:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12, state);break;
    case Timer13:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13, state);break;
    case Timer14:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, state);break;
    default:
        return;
    }
}

/*定时器时间配置*/
static void WHT_Timer_BSP_Set_Time(const WHT_Timer_Config_t* config)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    unsigned int Clk_Div;
	double Cycle;

	Cycle = config->Cycle_ns * ((double)SystemCoreClock / 1000000000.0f);
	switch(config->Name)//APB1 = APB2/2;
	{
	case Timer2:
	case Timer3:
	case Timer4:
	case Timer5:
	case Timer6:
	case Timer7:
	case Timer12:
	case Timer13:
	case Timer14:Cycle /= 2;break;
	}

    for (Clk_Div = 1; Clk_Div < 65536; Clk_Div++)
    {
        if ((Cycle / Clk_Div) <= 65536)
            break;
    }

	WHT_Timer_BSP_Clock_Cmd(config, ENABLE);
	/*计数器的时钟分频*/
	TIM_TimeBaseInitStruct.TIM_Prescaler = Clk_Div - 1;
	/*自动重装载寄存器值，累计TIM_Period+1个频率后产生一个更新或者中断*/
	TIM_TimeBaseInitStruct.TIM_Period = Cycle / Clk_Div - 1;
	/*保存自动重装载值即分辨率*/
	((WHT_Timer_Config_t*)config)->Auto_Reload = TIM_TimeBaseInitStruct.TIM_Period;
	/*时钟分频因子 ，配置死区时间要用*/
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	/*设置向上计数*/
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	/*重复计数器的值，没用到*/
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
	/*复位重置定时器，防止之前有残留配置*/
    TIM_DeInit((TIM_TypeDef*)config->Name);
	/*初始化配置定时器*/
    TIM_TimeBaseInit((TIM_TypeDef*)config->Name, &TIM_TimeBaseInitStruct);

    /*关闭所有中断*/
    TIM_ITConfig((TIM_TypeDef*)config->Name, TIM_IT_Update | TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4 | TIM_IT_COM | TIM_IT_Trigger | TIM_IT_Break, DISABLE);
    /*清除所有中断标志位*/
    TIM_ClearFlag((TIM_TypeDef*)config->Name, TIM_FLAG_Update | TIM_FLAG_CC1 | TIM_FLAG_CC2 |  TIM_FLAG_CC3 | TIM_FLAG_CC4 | TIM_FLAG_COM | TIM_FLAG_Trigger |\
                                               TIM_FLAG_Break | TIM_FLAG_CC1OF | TIM_FLAG_CC2OF | TIM_FLAG_CC3OF | TIM_FLAG_CC4OF);
    /*关闭计数器*/
    TIM_Cmd((TIM_TypeDef*)config->Name, DISABLE);
}
/*基本定时器*/
static void WHT_Timer_BSP_Basic(const WHT_Timer_Config_t* config)
{
	WHT_TIMER->Basic_IT_CB = ((WHT_Timer_Basic_Config_t*)config->Config)->Interrupt_Callback;
	WHT_TIMER->DMA_Config_UP.IT_Callback = WHT_TIMER->Basic_IT_CB;
	switch (config->Name)
	{
	case Timer1:WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM1_UP;          WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM1_UP;         break;
	case Timer2:WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM2_UP_TIM2_CH3; WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM2_UP_TIM2_CH3;break;
	case Timer3:WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM3_CH4_TIM3_UP; WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM3_CH4_TIM3_UP;break;
	case Timer4:WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM4_UP;          WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM4_UP;         break;
	case Timer5:WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM5_CH3_TIM5_UP; WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM5_CH3_TIM5_UP;break;
	case Timer6:WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM6_UP;          WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM6_UP;         break;
	case Timer7:WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM7_UP_1;        WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM7_UP_1;       break;
	case Timer8:WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM8_UP;          WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM8_UP;         break;
	default:return;
   	}
	TIM_DMACmd((TIM_TypeDef*)config->Name, TIM_DMA_Update, DISABLE);//关闭定时器DMA更新
	WHT_Timer_BSP_Basic_NVIC_Configuration(config);
	/*将注册到DMA上*/
	WHT_DMA_BSP.WHT_Register(&WHT_TIMER->DMA_Config_UP);
	/*开启更新中断*/
	TIM_ITConfig((TIM_TypeDef*)config->Name, TIM_IT_Update, ENABLE);
}
/*定时器输出触发*/
static void WHT_Timer_BSP_Output_Trigger(const WHT_Timer_Config_t* config)
{
	TIM_SelectOutputTrigger((TIM_TypeDef*)config->Name, ((WHT_Timer_Out_Trigger_Config_t*)config->Config)->Out_Trigger);
}
/*定时器输出比较PWM*/
static void WHT_Timer_BSP_Output_Comparison(const WHT_Timer_Config_t* config)
{
	WHT_Timer_PWM_Out_Config_t* PWM_Config = (WHT_Timer_PWM_Out_Config_t*)config->Config;

	switch (config->Name)
	{
	case Timer1:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM1_CH1_1;                 WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM1_CH1_1;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM1_CH2;                   WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM1_CH2;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM1_CH3;                   WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM1_CH3;
		WHT_TIMER->DMA_Config_CCR4.Stream = Stream_TIM1_CH4_TIM1_TRIG_TIM1_COM;WHT_TIMER->DMA_Config_CCR4.Channel = Channel_TIM1_CH4_TIM1_TRIG_TIM1_COM;
		break;
	case Timer2:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM2_CH1;          WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM2_CH1;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM2_CH2_TIM2_CH4; WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM2_CH2_TIM2_CH4;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM2_UP_TIM2_CH3;  WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM2_UP_TIM2_CH3;
		WHT_TIMER->DMA_Config_CCR4.Stream = Stream_TIM2_CH2_TIM2_CH4; WHT_TIMER->DMA_Config_CCR4.Channel = Channel_TIM2_CH2_TIM2_CH4;
		break;
	case Timer3:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM3_CH1_TIM3_TRIG; WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM3_CH1_TIM3_TRIG;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM3_CH2;           WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM3_CH2;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM3_CH3;           WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM3_CH3;
		WHT_TIMER->DMA_Config_CCR4.Stream = Stream_TIM3_CH4_TIM3_UP;   WHT_TIMER->DMA_Config_CCR4.Channel = Channel_TIM3_CH4_TIM3_UP;
		break;
	case Timer4:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM4_CH1;  WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM4_CH1;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM4_CH2;  WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM4_CH2;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM4_CH3;  WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM4_CH3;
		//WHT_TIMER->DMA_Config_CCR4.Stream = 0;                WHT_TIMER->DMA_Config_CCR4.Channel = 0;
		break;
	case Timer5:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM5_CH1;             WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM5_CH1;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM5_CH2;             WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM5_CH2;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM5_CH3_TIM5_UP;     WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM5_CH3_TIM5_UP;
		WHT_TIMER->DMA_Config_CCR4.Stream = Stream_TIM5_CH4_TIM5_TRIG_1; WHT_TIMER->DMA_Config_CCR4.Channel = Channel_TIM5_CH4_TIM5_TRIG_1;
		break;
	case Timer8:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM8_CH1;                    WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM8_CH1;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM8_CH2;                    WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM8_CH2;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM8_CH3;                    WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM8_CH3;
		WHT_TIMER->DMA_Config_CCR4.Stream = Stream_TIM8_CH4_TIM8_TRIG_TIM8_COM; WHT_TIMER->DMA_Config_CCR4.Channel = Channel_TIM8_CH4_TIM8_TRIG_TIM8_COM;
		break;
	default:break;
	}

	/*PWM输出及互补输出*/
	for (unsigned char i = 0; i < config->Config_Count; i++)
	{
		TIM_OCInitTypeDef  TIM_OCInitStruct;
		/*配置为PWM模式1*/
		TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
		/*输出使能*/
		TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
		/*占空比*/
		TIM_OCInitStruct.TIM_Pulse = 0;
		/*输出通道电平极性配置*/
		TIM_OCInitStruct.TIM_OCPolarity = PWM_Config[i].Normal_Polarity == Hig ? TIM_OCPolarity_High : TIM_OCPolarity_Low;
		/*输出通道空闲电平极性配置*/
		TIM_OCInitStruct.TIM_OCIdleState = PWM_Config[i].Normal_Idle_Polarity == Hig ? TIM_OCIdleState_Set : TIM_OCIdleState_Reset;
		
		/*******************互补输出*******************/
		TIM_OCInitStruct.TIM_OutputNState = PWM_Config[i].Complementary_Output_State == ENABLE ? TIM_OutputNState_Enable : TIM_OutputNState_Disable;
		if (PWM_Config[i].Complementary_Output_State == ENABLE)
		{
			/*互补输出通道电平极性配置*/
			TIM_OCInitStruct.TIM_OCNPolarity = PWM_Config[i].CO_Polarity == Hig ? TIM_OCNPolarity_High : TIM_OCNPolarity_Low;
			/*互补输出通道空闲电平极性配置*/
			TIM_OCInitStruct.TIM_OCNIdleState = PWM_Config[i].CO_Idle_Polarity == Hig ? TIM_OCNIdleState_Set : TIM_OCNIdleState_Reset;
		}

		if (PWM_Config[i].Channel == Timer_CH1)
		{
			TIM_OC1Init((TIM_TypeDef*)config->Name, &TIM_OCInitStruct);
			TIM_OC1PreloadConfig((TIM_TypeDef*)config->Name, TIM_OCPreload_Enable);//影子寄存器开启
			/*将注册到DMA上*/
			WHT_TIMER->DMA_Config_CCR1.IT_Callback = PWM_Config[i].Idle_IT_Callback;
			WHT_DMA_BSP.WHT_Register(&WHT_TIMER->DMA_Config_CCR1);
		}
		else if (PWM_Config[i].Channel == Timer_CH2)
		{
			TIM_OC2Init((TIM_TypeDef*)config->Name, &TIM_OCInitStruct);
			TIM_OC2PreloadConfig((TIM_TypeDef*)config->Name, TIM_OCPreload_Enable);//影子寄存器开启
			/*将注册到DMA上*/
			WHT_TIMER->DMA_Config_CCR2.IT_Callback = PWM_Config[i].Idle_IT_Callback;//定时器3没有通道2的DMA 注意
			WHT_DMA_BSP.WHT_Register(&WHT_TIMER->DMA_Config_CCR2);
		}
		else if (PWM_Config[i].Channel == Timer_CH3)
		{
			TIM_OC3Init((TIM_TypeDef*)config->Name, &TIM_OCInitStruct);
			TIM_OC3PreloadConfig((TIM_TypeDef*)config->Name, TIM_OCPreload_Enable);//影子寄存器开启
			/*将注册到DMA上*/
			WHT_TIMER->DMA_Config_CCR3.IT_Callback = PWM_Config[i].Idle_IT_Callback;
			WHT_DMA_BSP.WHT_Register(&WHT_TIMER->DMA_Config_CCR3);
		}
		else if (PWM_Config[i].Channel == Timer_CH4)
		{
			TIM_OC4Init((TIM_TypeDef*)config->Name, &TIM_OCInitStruct);
			TIM_OC4PreloadConfig((TIM_TypeDef*)config->Name, TIM_OCPreload_Enable);//影子寄存器开启
			/*将注册到DMA上*/
			WHT_TIMER->DMA_Config_CCR4.IT_Callback = PWM_Config[i].Idle_IT_Callback;
			WHT_DMA_BSP.WHT_Register(&WHT_TIMER->DMA_Config_CCR4);
		}
	}
}
/*高级定时器刹车和死区*/
static void WHT_Timer_BSP_Break(const WHT_Timer_Config_t* config)
{
	WHT_Timer_PWM_Out_Config_t* PWM_Config = (WHT_Timer_PWM_Out_Config_t*)config->Config;
	TIM_BDTRInitTypeDef TIM_BDTRInitStruct;

	for (unsigned char i = 0; i < config->Config_Count; i++)
	{
		/*有关刹车和死区结构体的成员具体可参考BDTR寄存器的描述*/
		TIM_BDTRInitStruct.TIM_Break = PWM_Config[i].Brake_Output_State == ENABLE ? TIM_Break_Enable : TIM_Break_Disable;
		if (PWM_Config[i].Brake_Output_State == ENABLE)
		{
			TIM_BDTRInitStruct.TIM_OSSRState = TIM_OSSRState_Enable;
			TIM_BDTRInitStruct.TIM_OSSIState = TIM_OSSIState_Enable;
			TIM_BDTRInitStruct.TIM_LOCKLevel = TIM_LOCKLevel_OFF;//TIM_LOCKLevel_1;//寄存器写保护
			/*输出比较信号死区时间配置，具体如何计算可参考 BDTR:UTG[7:0]的描述*/
			/* 死区时间配置 (典型值500ns:36,152ns:11) */
			TIM_BDTRInitStruct.TIM_DeadTime = 36;
			TIM_BDTRInitStruct.TIM_Break = TIM_Break_Disable;////////TIM_Break_Enable;//刹车输入检测
			/*当BKIN引脚检测到高电平的时候，输出比较信号被禁止，刹车*/
			TIM_BDTRInitStruct.TIM_BreakPolarity = TIM_BreakPolarity_Low;
			TIM_BDTRInitStruct.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
		}
		TIM_BDTRConfig((TIM_TypeDef*)config->Name, &TIM_BDTRInitStruct);
	}
}
/*定时器输入捕获*/
static void WHT_Timer_BSP_Input_Capture(const WHT_Timer_Config_t* config)//目前未调试未完成
{
	// 使用PWM输入模式时，需要占用两个捕获寄存器，一个测周期，另外一个测占空比
	TIM_ICInitTypeDef  TIM_ICInitStructure;
	// 捕获通道IC1配置
	// 选择捕获通道
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	// 设置捕获的边沿
	TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
	// 设置捕获通道的信号来自于哪个输入通道，有直连和非直连两种
	TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
	// 1分频，即捕获信号的每个有效边沿都捕获
	TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	// 不滤波
	TIM_ICInitStructure.TIM_ICFilter = 0;
	// 初始化PWM输入模式
	TIM_PWMIConfig((TIM_TypeDef*)config->Name, &TIM_ICInitStructure);
			
	// 当工作做PWM输入模式时,只需要设置触发信号的那一路即可（用于测量周期）
	// 另外一路（用于测量占空比）会由硬件自带设置，不需要再配置
		
	// 捕获通道IC2配置
	//	TIM_ICInitStructure.TIM_Channel = ADVANCE_TIM_IC1PWM_CHANNEL;
	//  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
	//  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;
	//  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	//  TIM_ICInitStructure.TIM_ICFilter = 0x0;
	//  TIM_PWMIConfig((TIM_TypeDef*)config->Name, &TIM_ICInitStructure);
		
	// 选择输入捕获的触发信号
	TIM_SelectInputTrigger((TIM_TypeDef*)config->Name, TIM_TS_TI1FP1);

	// 选择从模式: 复位模式
	// PWM输入模式时,从模式必须工作在复位模式，当捕获开始时,计数器CNT会被复位
	TIM_SelectSlaveMode((TIM_TypeDef*)config->Name, TIM_SlaveMode_Reset);
	TIM_SelectMasterSlaveMode((TIM_TypeDef*)config->Name,TIM_MasterSlaveMode_Enable);

	// 使能捕获中断,这个中断针对的是主捕获通道（测量周期那个）
	TIM_ITConfig((TIM_TypeDef*)config->Name, TIM_IT_CC1, ENABLE);
	// 清除中断标志位
	TIM_ClearITPendingBit((TIM_TypeDef*)config->Name, TIM_IT_CC1);
}
/*定时器配置*/
static void WHT_Timer_BSP_Config(const WHT_Timer_Config_t* config)
{
    if (config->Private_Data != NULL)
        return;

	switch (config->Name)
	{
	case Timer1:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER1; break;
	case Timer2:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER2; break;
	case Timer3:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER3; break;
	case Timer4:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER4; break;
	case Timer5:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER5; break;
	case Timer6:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER6; break;
	case Timer7:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER7; break;
	case Timer8:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER8; break;
	case Timer9:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER9; break;
	case Timer10:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER10; break;
	case Timer11:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER11; break;
	case Timer12:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER12; break;
	case Timer13:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER13; break;
	case Timer14:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER14; break;
	default: return;
	}

	WHT_Timer_BSP_Set_Time(config);
	if (config->Mode == Timer_Basic)//基本定时
	{
		WHT_Timer_BSP_Basic(config);
	}
	else if (config->Mode == Timer_Output_Trigger)
	{
		WHT_Timer_BSP_Output_Trigger(config);
	}
	else if (config->Mode == Timer_Output_Comparison)//输出比较
	{
		WHT_Timer_BSP_GPIO_Init(config);
		WHT_Timer_BSP_Output_Comparison(config);
		WHT_Timer_BSP_Break(config);
		/*主输出使能，当使用的是通用定时器时，这句可不需要*/
		TIM_CtrlPWMOutputs((TIM_TypeDef*)config->Name, ENABLE);
	}
	else if (config->Mode == Timer_Input_Capture)//输入捕获
	{
		WHT_Timer_BSP_GPIO_Init(config);
		WHT_Timer_BSP_Input_Capture(config);
	}
	TIM_Cmd((TIM_TypeDef*)config->Name, DISABLE);//关闭计数器
}


/*高级定时器设置周期*/
static void WHT_Timer_BSP_Set_Cycle(const WHT_Timer_Config_t* config)
{
	unsigned int Clk_Div;
	double Cycle;

	Cycle = config->Cycle_ns * ((double)SystemCoreClock / 1000000000.0);
    for (Clk_Div = 1; Clk_Div < 65536; Clk_Div++)
    {
        if (Cycle / Clk_Div <= 65536)
            break;
    }
	/*保存自动重装载值即分辨率*/
	((WHT_Timer_Config_t*)config)->Auto_Reload = Cycle / Clk_Div - 1;
	/*设置预分频*/
	TIM_PrescalerConfig((TIM_TypeDef*)config->Name, Clk_Div - 1, TIM_PSCReloadMode_Update);
	/*设置自动重装载值*/
	TIM_SetAutoreload((TIM_TypeDef*)config->Name, config->Auto_Reload);
}
/*高级定时器设置占空比*/
static void WHT_Timer_BSP_Set_Duty_Cycle(const WHT_Timer_Config_t* config, WHT_Timer_Channel_enum channel, float duty_cycle)
{
	unsigned short compare_value = (unsigned short)(config->Auto_Reload * duty_cycle / 100.0f);

	switch (channel)
	{
	case Timer_CH1:TIM_SetCompare1((TIM_TypeDef*)config->Name, compare_value);break;
	case Timer_CH2:TIM_SetCompare2((TIM_TypeDef*)config->Name, compare_value);break;
	case Timer_CH3:TIM_SetCompare3((TIM_TypeDef*)config->Name, compare_value);break;
	case Timer_CH4:TIM_SetCompare4((TIM_TypeDef*)config->Name, compare_value);break;
	default:
		break;
	}
}
/*高级、通用定时器 每个周期DMA修改缓存里的占空比*/
static void WHT_Timer_BSP_DMA_Set_Duty_Cycle(const WHT_Timer_Config_t* config, WHT_Timer_Channel_enum channel, unsigned char* duty_cycle_buffer, unsigned short duty_cycle_count)
{
	WHT_DMA_Config_t* DMA_Send_Config_CCRx;
    DMA_InitTypeDef DMA_InitStruct =
    {
        .DMA_Channel            = 0,                          //DMA通道
        .DMA_PeripheralBaseAddr = 0,                          //外设基地址
        .DMA_Memory0BaseAddr    = 0,                          //存储器地址
        .DMA_DIR                = DMA_DIR_MemoryToPeripheral, //M->P
        .DMA_BufferSize         = 0,                          //传输个数
        .DMA_PeripheralInc      = DMA_PeripheralInc_Disable,  //外设地址不递增
        .DMA_MemoryInc          = DMA_MemoryInc_Enable,       //存储器地址递增
        .DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord,//外设数据大小为2字节
        .DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte,    //存储器数据大小为1字节，这里注意 最大占空比值为255 对于WS2812B够用了哈
        .DMA_Mode               = DMA_Mode_Normal,            //单次传输模式
        .DMA_Priority           = DMA_Priority_Medium,        //优先级最低
        .DMA_FIFOMode           = DMA_FIFOMode_Disable,       //FIFO模式
        .DMA_FIFOThreshold      = DMA_FIFOThreshold_1QuarterFull,//FIFO阈值
        .DMA_MemoryBurst        = DMA_MemoryBurst_Single,     //内存突发传输
        .DMA_PeripheralBurst    = DMA_PeripheralBurst_Single, //外设突发传输
    };
	
	switch (channel)
	{
	case Timer_CH1:
		DMA_Send_Config_CCRx = &WHT_TIMER->DMA_Config_CCR1;
		DMA_InitStruct.DMA_PeripheralBaseAddr = (unsigned int)&((TIM_TypeDef*)config->Name)->CCR1;break;//外设基地址
	case Timer_CH2:
		DMA_Send_Config_CCRx = &WHT_TIMER->DMA_Config_CCR2;
		DMA_InitStruct.DMA_PeripheralBaseAddr = (unsigned int)&((TIM_TypeDef*)config->Name)->CCR2;break;
	case Timer_CH3:
		DMA_Send_Config_CCRx = &WHT_TIMER->DMA_Config_CCR3;
		DMA_InitStruct.DMA_PeripheralBaseAddr = (unsigned int)&((TIM_TypeDef*)config->Name)->CCR3;break;
	case Timer_CH4:
		DMA_Send_Config_CCRx = &WHT_TIMER->DMA_Config_CCR4;
		DMA_InitStruct.DMA_PeripheralBaseAddr = (unsigned int)&((TIM_TypeDef*)config->Name)->CCR4;break;
	default:
		return;
	}

	DMA_InitStruct.DMA_Channel = DMA_Send_Config_CCRx->Channel;          //DMA通道
    DMA_InitStruct.DMA_Memory0BaseAddr = (unsigned int)duty_cycle_buffer;//数据源首地址
    DMA_InitStruct.DMA_BufferSize = duty_cycle_count;                    //传输数据个数
	DMA_Send_Config_CCRx->DMA_InitStruct = &DMA_InitStruct;
    while (DMA_Send_Config_CCRx->Info->BSP_Mutex == SET);//等待没有外设使用此通道的DMA
    DMA_Send_Config_CCRx->Info->BSP_Mutex = SET;         //DMA通道上锁
    WHT_DMA_BSP.WHT_Config(DMA_Send_Config_CCRx);        //配置当前DMA

	/*使能DMA发送请求*/
	switch (channel)
	{
	case Timer_CH1:TIM_DMACmd((TIM_TypeDef *)config->Name, TIM_DMA_CC1, ENABLE);break;
	case Timer_CH2:TIM_DMACmd((TIM_TypeDef *)config->Name, TIM_DMA_CC2, ENABLE);break;
	case Timer_CH3:TIM_DMACmd((TIM_TypeDef *)config->Name, TIM_DMA_CC3, ENABLE);break;
	case Timer_CH4:TIM_DMACmd((TIM_TypeDef *)config->Name, TIM_DMA_CC4, ENABLE);break;
	default:
		return;
	}
	TIM_Cmd((TIM_TypeDef *)config->Name, ENABLE);
}
/*基本定时器启动*/
static void WHT_Timer_BSP_Start(const WHT_Timer_Config_t* config)
{
    TIM_Cmd((TIM_TypeDef*)config->Name, ENABLE);
}
/*基本定时器暂停*/
static void WHT_Timer_BSP_Stop(const WHT_Timer_Config_t* config)
{
    TIM_Cmd((TIM_TypeDef*)config->Name, DISABLE);
}


/*全局常量*/
const WHT_Timer_BSP_t WHT_Timer_BSP =
{
	.WHT_Config         = WHT_Timer_BSP_Config,
	.WHT_Set_Cycle_ns   = WHT_Timer_BSP_Set_Cycle,
	.WHT_Set_Duty_Cycle = WHT_Timer_BSP_Set_Duty_Cycle,
	.WHT_Set_Duty_Cycle_DMA = WHT_Timer_BSP_DMA_Set_Duty_Cycle,
	.WHT_Start          = WHT_Timer_BSP_Start,
	.WHT_Stop           = WHT_Timer_BSP_Stop,
};




/*基本定时器更新中断回调函数*/
static void WHT_Timer_Basic_IRQHandler(TIM_TypeDef* TIMx, void (*IT_CB)(void))
{
    if (TIM_GetITStatus(TIMx, TIM_IT_Update) == SET)
    {
        if (IT_CB)
			IT_CB();
        TIM_ClearITPendingBit(TIMx, TIM_IT_Update);
    }
}
/*通用高级定时器捕获/比较中断回调函数*/
static void WHT_Timer_CCx_IRQHandler(TIM_TypeDef* TIMx, void (*IT_CB)(void))
{
    if (TIM_GetITStatus(TIMx, TIM_IT_CC1) == SET)
    {
        if (IT_CB)
			IT_CB();
        TIM_ClearITPendingBit(TIMx, TIM_IT_CC1);
    }
    else if (TIM_GetITStatus(TIMx, TIM_IT_CC2) == SET)
    {
        if (IT_CB)
			IT_CB();
        TIM_ClearITPendingBit(TIMx, TIM_IT_CC2);
    }
    else if (TIM_GetITStatus(TIMx, TIM_IT_CC3) == SET)
    {
        if (IT_CB)
			IT_CB();
        TIM_ClearITPendingBit(TIMx, TIM_IT_CC3);
    }
    else if (TIM_GetITStatus(TIMx, TIM_IT_CC4) == SET)
    {
        if (IT_CB)
			IT_CB();
        TIM_ClearITPendingBit(TIMx, TIM_IT_CC4);
    }
}
/*通用高级定时器输出比较中断回调函数*/
static void WHT_Timer_COM_IRQHandler(TIM_TypeDef* TIMx, void (*IT_CB)(void))
{
    if (TIM_GetITStatus(TIMx, TIM_IT_COM) == SET)
    {
        if (IT_CB)
			IT_CB();
        TIM_ClearITPendingBit(TIMx, TIM_IT_COM);
    }
}
/*通用高级定时器触发中断回调函数*/
static void WHT_Timer_Trigge_IRQHandler(TIM_TypeDef* TIMx, void (*IT_CB)(void))
{
    if (TIM_GetITStatus(TIMx, TIM_IT_Trigger) == SET)
    {
        if (IT_CB)
			IT_CB();
        TIM_ClearITPendingBit(TIMx, TIM_IT_Trigger);
    }
}
/*高级定时器刹车中断回调函数*/
static void WHT_Timer_Break_IRQHandler(TIM_TypeDef* TIMx, void (*IT_CB)(void))
{
    if (TIM_GetITStatus(TIMx, TIM_IT_Break) == SET)
    {
        if (IT_CB)
			IT_CB();
        TIM_ClearITPendingBit(TIMx, TIM_IT_Break);
    }
}


/*定时器1更新中断服务程序*/
void TIM1_UP_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM1, WHT_TIMER1.Basic_IT_CB);
}
void TIM1_UP_TIM10_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM1, TIM_IT_Update) == SET)
	{
		WHT_Timer_Basic_IRQHandler(TIM1, WHT_TIMER1.Basic_IT_CB);
	}
    else if (TIM_GetITStatus(TIM10, TIM_IT_Update) == SET)
	{
		WHT_Timer_Basic_IRQHandler(TIM10, WHT_TIMER10.Basic_IT_CB);
	}
}
/*定时器2中断服务程序*/
void TIM2_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM2, WHT_TIMER2.Basic_IT_CB);
}
/*定时器3中断服务程序*/
void TIM3_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM3, WHT_TIMER3.Basic_IT_CB);
}
/*定时器4中断服务程序*/
void TIM4_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM4, WHT_TIMER4.Basic_IT_CB);
}
/*定时器5中断服务程序*/
void TIM5_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM5, WHT_TIMER5.Basic_IT_CB);
}
/*定时器6中断服务程序*/
void TIM6_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM6, WHT_TIMER6.Basic_IT_CB);
}
void TIM6_DAC_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM6, WHT_TIMER6.Basic_IT_CB);
}
/*定时器7中断服务程序*/
void TIM7_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM7, WHT_TIMER7.Basic_IT_CB);
}
/*定时器8更新中断服务程序*/
void TIM8_UP_TIM13_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM8, WHT_TIMER8.Basic_IT_CB);
}
/*定时器9更新中断服务程序*/
void TIM1_BRK_TIM9_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM9, WHT_TIMER9.Basic_IT_CB);
}
/*定时器11更新中断服务程序*/
void TIM1_TRG_COM_TIM11_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM11, WHT_TIMER11.Basic_IT_CB);
}
/*定时器12更新中断服务程序*/
void TIM8_BRK_TIM12_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM12, WHT_TIMER12.Basic_IT_CB);
}
/*定时器13更新中断服务程序*/
void TIM8_BRK_TIM13_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM13, WHT_TIMER13.Basic_IT_CB);
}
/*定时器14更新中断服务程序*/
void TIM8_TRG_COM_TIM14_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(TIM14, WHT_TIMER14.Basic_IT_CB);
}
